﻿using System.IO;
using System.Text;
using System.Xml.Serialization;
using System.Xml;

namespace Hl.Core.Helper;
public class XmlHelper
{
    /// <summary>
    /// 实例转xml
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="toSerialize"></param>
    /// <param name="standalone">单文档、整个文件</param>
    /// <returns></returns>
    public static string SerializeObjectToXml<T>(T toSerialize, bool standalone=true) where T : class
    {
        XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
        using (MemoryStream memoryStream = new MemoryStream())
        {
            // 使用encoding编码和无BOM的XmlWriterSettings
            XmlWriterSettings settings = new XmlWriterSettings
            {
                Encoding = new UTF8Encoding(false),
                Indent = true, // 可选的，如果你想要格式化的XML
                OmitXmlDeclaration = false, // 可选的，如果你想要包含XML声明
            };

            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
            namespaces.Add(string.Empty, string.Empty);

            using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, settings))
            {
                xmlWriter.WriteStartDocument(standalone);
                xmlSerializer.Serialize(xmlWriter, toSerialize, namespaces);
            }
            // 将MemoryStream的内容转换为 realEncoding 字符串
            return Encoding.UTF8.GetString(memoryStream.ToArray());
        }
    }


    /// <summary>
    /// 反序列化xml
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="xmlStr">xml 文件内容</param>
    /// <returns></returns>
    public static T DeserializeXmlToObject<T>(string xmlStr) where T : class
    {
        XmlDocument xDoc = new XmlDocument();
        try
        {
            xDoc.LoadXml(xmlStr);
            XmlNodeReader reader = new XmlNodeReader(xDoc.DocumentElement);
            XmlSerializer serial = new XmlSerializer(typeof(T));
            object obj = serial.Deserialize(reader);
            return (T)obj;
        }
        catch (Exception)
        {
            return default;
        }
    }
}